package vip.aster.system.service.impl;

import cn.hutool.core.lang.UUID;
import cn.hutool.core.util.StrUtil;
import com.wf.captcha.*;
import com.wf.captcha.base.Captcha;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import vip.aster.common.captcha.MathCaptcha;
import vip.aster.common.config.AsterConfig;
import vip.aster.common.constant.CacheConstants;
import vip.aster.common.constant.enums.CaptchaTypeEnum;
import vip.aster.common.constant.Constants;
import vip.aster.common.utils.CacheUtils;
import vip.aster.system.service.SysCaptchaService;
import vip.aster.system.service.SysConfigService;
import vip.aster.system.vo.SysCaptchaVO;

import java.util.concurrent.TimeUnit;

/**
 * 验证码实现类
 *
 * @author Aster
 * @since 2023/11/30 10:49
 */
@Service
@AllArgsConstructor
public class SysCaptchaServiceImpl implements SysCaptchaService {
    private AsterConfig asterConfig;
    private SysConfigService configService;

    /**
     * 图片宽度
     */
    private static final int WIDTH = 120;
    /**
     * 图片高度
     */
    private static final int HEIGHT = 40;

    @Override
    public SysCaptchaVO generate() {
        // 生成验证码key
        String key = UUID.randomUUID().toString();
        // 验证码值
        String value = "";
        // 验证码图片
        String image = "";
        // 验证码类型
        String captchaType = asterConfig.getCaptchaType();

        if (CaptchaTypeEnum.MATH.getValue().equals(captchaType)) {
            MathCaptcha arithmeticCaptcha = new MathCaptcha(WIDTH, HEIGHT, 2);
            value = arithmeticCaptcha.text();
            image = arithmeticCaptcha.toBase64();
        } else if (CaptchaTypeEnum.CHINESE.getValue().equals(captchaType)) {
            ChineseCaptcha chineseCaptcha = new ChineseCaptcha(WIDTH, HEIGHT, 4);
            value = chineseCaptcha.text();
            image = chineseCaptcha.toBase64();
        } else if (CaptchaTypeEnum.GIF.getValue().equals(captchaType)) {
            GifCaptcha gifCaptcha = new GifCaptcha(WIDTH, HEIGHT, 4);
            value = gifCaptcha.text();
            image = gifCaptcha.toBase64();
        } else if (CaptchaTypeEnum.CHINESE_GIF.getValue().equals(captchaType)) {
            ChineseGifCaptcha chineseGifCaptcha = new ChineseGifCaptcha(WIDTH, HEIGHT, 4);
            value = chineseGifCaptcha.text();
            image = chineseGifCaptcha.toBase64();
        } else {
            // 生成字符验证码
            SpecCaptcha captcha = new SpecCaptcha(WIDTH, HEIGHT, 4);
            captcha.setCharType(Captcha.TYPE_ONLY_CHAR);
            value = captcha.text();
            image = captcha.toBase64();
        }
        // 保存到缓存
        CacheUtils.set(CacheConstants.CAPTCHA_CODE_KEY, key, value, Constants.CAPTCHA_EXPIRATION, TimeUnit.MINUTES);
        // 封装返回数据
        SysCaptchaVO captchaVO = new SysCaptchaVO();
        captchaVO.setKey(key);
        captchaVO.setImage(image);

        return captchaVO;
    }

    @Override
    public boolean validate(String key, String code) {
        // 如果关闭了验证码，则直接效验通过
        if (!isCaptchaEnabled()) {
            return true;
        }

        if (StrUtil.isBlank(key) || StrUtil.isBlank(code)) {
            return false;
        }
        // 获取验证码
        String captcha  = CacheUtils.get(CacheConstants.CAPTCHA_CODE_KEY, key, String.class);
        // 删除验证码
        if (StrUtil.isNotBlank(captcha)) {
            CacheUtils.deleteIfPresent(CacheConstants.CAPTCHA_CODE_KEY, key);
        }
        // 效验成功
        return code.equalsIgnoreCase(captcha);
    }

    @Override
    public boolean isCaptchaEnabled() {
        return configService.selectCaptchaOnOff();
    }
}
